package com.shen.xiang.test.mybatis;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;

import java.util.Set;

public class ClassPathConfig extends ClassPathBeanDefinitionScanner {

    private Class MapperFactoryclass = MyMapperFactoryBean.class;
    private String DefaultSqlSessionFactory = "defaultSqlSessionFactory";
    public ClassPathConfig(BeanDefinitionRegistry registry) {
        super(registry);
    }

    @Override
    public Set<BeanDefinitionHolder> doScan(String... basePackages) {
        GenericBeanDefinition beanDefinition;
        Set<BeanDefinitionHolder> holders = super.doScan(basePackages);
        //对象扫描出来的beandefinition进行修改
        for (BeanDefinitionHolder holder : holders) {
            beanDefinition = (GenericBeanDefinition) holder.getBeanDefinition();
            //获取bean的class类
            String beanClassName = beanDefinition.getBeanClassName();
            //设置beandefinition的构造参数
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
            //重新设置这个beandefinition的Class类
            beanDefinition.setBeanClass(this.MapperFactoryclass);
            //设置自动注入方式 1为按名字注入 2为按类型注入
            //在这个beandefinition属性注入阶段 会判断是否是自动注入 如果是 会判断这个bean需要注入哪些属性
            beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }
        return holders;
    }

    /**
     * 注册过滤器 来过滤些不是mapper接口的类
     */
    public void registerFilters() {
        boolean acceptAllInterfaces = true;
//        if (this.annotationClass != null) {
//            this.addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));
//            acceptAllInterfaces = false;
//        }
//
//        if (this.markerInterface != null) {
//            this.addIncludeFilter(new AssignableTypeFilter(this.markerInterface) {
//                protected boolean matchClassName(String className) {
//                    return false;
//                }
//            });
//            acceptAllInterfaces = false;
//        }

        if (acceptAllInterfaces) {
            this.addIncludeFilter((metadataReader, metadataReaderFactory) -> {
                return true;
            });
        }

        this.addExcludeFilter((metadataReader, metadataReaderFactory) -> {
            String className = metadataReader.getClassMetadata().getClassName();
            return className.endsWith("package-info");
        });
    }

    /**
     * 判断是否是组件
     * @param beanDefinition
     * @return
     */
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
    }
}
